/*
 * Exploder
 * 
 * Tero Pyylampi (218437), Jussi Tuurinkoski (211594)
 *
 * Camera object for the game,
 * move the parallax node and handles the coordinate transformations
 */

#ifndef GAMECAMERA_H
#define GAMECAMERA_H

#include "cocos2d.h"
#include "Box2D/Box2D.h"

#include "../Common.h"

// transition style used in camera
enum ActionStyle {
	ACTION_LINEAR, ACTION_SPEEDING, ACTION_SLOWING, ACTION_COMBINED
};

class GameCamera {
public:
	// default constructor
	GameCamera( cocos2d::CCParallaxNode *node );
	// default destructor
	~GameCamera();

	// update camera
	void update( cocos2d::ccTime dt );

	// camera modifiers

	// set acceleration, main function to move camera
	void setCameraSpeed( cocos2d::CCPoint &speed );
	// move camera by certain amount
	void moveCamera( cocos2d::CCPoint &amount );
	// to move the world
	void setWorldPosition( cocos2d::CCPoint &position );
	// set zoom speed
	void setZoomSpeed( float speed, cocos2d::CCPoint &zoomPosition );

	// position offset for effects
	void setPositionOffset( float x, float y );

	// set new target point for camera to look
	void setNewCameraTarget( float x, float y, float timeToTake, ActionStyle style = ACTION_SLOWING );
	// set new zoom level target
	void setNewZoomTarget( float x, float y, float zoomLevel, float timeToTake, ActionStyle style = ACTION_SLOWING );

	// coordinate translations

	// convert world coordinates to screen coordinates
	b2Vec2 convertWorldToScreen( b2Vec2 &world );
	cocos2d::CCPoint convertWorldToScreen( float world_x, float world_y );
	// convert screen coordinates to world coordinates
	b2Vec2 convertScreenToWorld( b2Vec2 &screen );
	cocos2d::CCPoint convertScreenToWorld( float screen_x, float screen_y );

	// current attributes

	// set new camera lock state
	void setCameraLockState( bool state );
	// get current camera lock state
	bool getCameraLockState();

	// zoom level
	float getCurrentZoomLevel();
	// current position
	cocos2d::CCPoint getCurrentPosition();
	//b2Vec2 getCurrentPositionWorldCoords();
	// zoom speed
	float getCurrentZoomSpeed();

private:
	// parallax object to be controlled
	cocos2d::CCParallaxNode *mParallaxNode;

	// camera lock state, true = camera locked, false = camera can be moved freely
	bool mCameraLockState;

	// current speed
	cocos2d::CCPoint mCurrentSpeed;
	// acceleration speed
	static const float mAcceleration;

	// move camera offset
	cocos2d::CCPoint mMoveCamera;
	// whether the action is valid
	bool mMoveActionValid;

	// position offset
	cocos2d::CCPoint mPosOffset;

	// zoom stage
	float mCurrentZoom;
	// zoom speed
	float mZoomSpeed;
	// zoom acceleration
	static const float mZoomAcceleration;
	// zoom limits
	static const float mMaxZoom;
	static const float mMinZoom;
	// zoom target point
	cocos2d::CCPoint mZoomPoint;

	// absolute value function to keep android compiler happy...
	float abs( float value );

	// temporary variables used in the code for optimizations
	cocos2d::CCPoint mFinalSpeed;
	cocos2d::CCPoint mTmpPosition;

	// struct to withold parameters for different automated camera methods
	struct MCameraAction {
		// whether the first frame has passed (disable a small lag effect)
		bool framePassed;

		// from where the action started
		cocos2d::CCPoint startingPos;
		// where this camera is to be located
		cocos2d::CCPoint finalPos;
		
		// which zoom level the action started
		float startingZoom;
		// which zoom level is to be reached
		float finalZoom;

		// how long the transition should take
		float transitionTime;
		// time left from the ongoing transition
		float timeLeft;

		// transition style
		ActionStyle actionStyle;
	};
	MCameraAction *mCameraAction;

	// updates camera action
	void updateCameraAction( cocos2d::ccTime dt );
};

#endif